const { verifyToken } = require("../services/tokenService");
// 引入 UsersModel 用于查询用户状态
const UsersModel = require("../model/UsersModel");
const usersModel = new UsersModel(); // 实例化 Model

/**
 * JWT 身份验证中间件：用于校验 Token 的有效性和登录状态，并实现滑动会话续期。
 * * 机制：
 * 1. 检查请求头，获取 Token。
 * 2. 调用 tokenService.verifyToken (执行 JWT 签名校验、Redis 状态检查、滑动续期)。
 * 3. Token 通过后，调用 UsersModel.findUserById 检查用户是否被禁用，并获取最新角色信息。
 * 4. 校验通过，挂载用户信息到 req 对象。
 */
async function authMiddleware(req, res, next) {
  // 1. 获取 Token
  const authHeader = req.headers.authorization;
  if (!authHeader || !authHeader.startsWith("Bearer ")) {
    return res
      .status(401)
      .json({ code: 1, msg: "未授权：请提供有效的Token。" });
  }
  const token = authHeader.split(" ")[1];

  // 2. 校验 Token (包含 Redis 状态检查和续期)
  const result = await verifyToken(token);

  if (!result.valid) {
    // 校验失败 (签名无效、Token过期或已被注销)
    return res
      .status(401)
      .json({ code: 1, msg: `Token 验证失败: ${result.message}` });
  }

  // 3. Token 格式和 Redis 状态通过，进行 DB 状态检查 (即时禁用/角色更新)
  try {
    const user = await usersModel.findUserById(result.userId);

    // 检查用户是否存在或是否被禁用 (假设 status=1 为启用)
    if (!user || user.status !== 1) {
      // 尽管 Token 有效，但用户已被禁用。安全起见，应作废 Token
      if (result.tokenId)
        await require("../services/tokenService").revokeToken(result.tokenId);
      return res
        .status(401)
        .json({ code: 1, msg: "身份验证失败：用户不存在或已被禁用。" });
    }

    // 4. 校验通过，将最新用户信息和 Token ID 挂载到请求对象上
    req.userId = user.user_id; // 确保使用DB中最新的ID
    req.roleId = user.role_id; // 确保使用DB中最新的角色
    req.user = user; // 挂载完整用户信息
    req.tokenId = result.tokenId; // 用于主动退出 (logout)

    next();
  } catch (error) {
    console.error(error.message);
    return res.status(500).json({ code: 1, msg: "服务器认证处理失败。" });
  }
}

module.exports = authMiddleware;
